


#' Make unique names for a modication-enriched peptide table
#'
#' \code{make_unique_ptm} generates unique identifiers
#' for a proteomics dataset based on "modified_name" columns.
#' If "modified_name" is absent, it will creat a modified name
#' based on "gene_name"/"Protein", "aa" and "pos".
#'
#' @param PTMdata Data.frame, modified peptide table
#' for which unique names and ID for each modified peptide will be created.
#' @param gene_name Character(1),
#' Name of the column containing gene symbol or protein name.
#' @param protein_ID Character(1),
#' Name of the column containing protein ID or gene ID.
#' @param aa Character(1),
#' Name of the column containing abbreviation of modified amino acid, e.g. "K", "S", "T".
#' It is unnecessary if \code{modified_name} is provided.
#' @param pos Character(1),
#' Name of the column containing position of modification on proteins.
#' It is unnecessary if \code{modified_name} is provided.
#' @param delim Character(1),
#' Sets the delimiter separating the multiple feature names within one protein group(gene_name and protein_ID).
#' @param modified_name Character(1),
#' Name of the column containing names of modified peptide in the format
#' (gene name)_(modified amino acid)(position of modification), e.g. "TBCA_K51".
#' @return A data.frame with the 6 additional variables
#' "name" and "ID" containing unique names and identifiers or modified peptide respectively, e.g. "TBCA_K51" and "O75347_K51".
#' And "gene_name", protein_ID" save protein information of modified peptide, e.g. "TBCA" and "O75347".
#' "modified_aa" and "modified_pos" is the modified amino acid and position, e.g. "K" and "51".
#'
#' @details
#' If modified_name is provide, gene_name, protein_ID, aa and pos are unnessary.
#' Additional variables is generated by parsing modified_name.
#' else gene_name or protein_ID, aa and pos are nessary.
#' @export
#'
#' @examples
#' ## phosphorylated peptides table of the silicosis mouse model.
#' data(Silicosis_phos)
#' ## Format the modification information and generated modified-peptides identifier.
#' unique_pho <- make_unique_ptm(Silicosis_phos, gene_name = "Gene.names",
#'                               protein_ID = "Protein", aa = "Amino.acid",
#'                               pos = "Position")
#' head(unique_pho[, c("name","ID")], 10)
#'
make_unique_ptm <- function(PTMdata, gene_name = "Gene.names", protein_ID = "Protein",
                            aa = "Amino.acid", pos = "Position",
                            modified_name = NULL,
                            delim = ";"
){
  data = PTMdata
  if(is.null(gene_name)&is.null(protein_ID) & is.null(modified_name)){
    stop("at least one of gene_name or protein_ID are necessary when modified_name is NULL, please give a correct input")
  }else if(is.null(modified_name) && (is.null("aa")| is.null("pos"))){
    stop("If modified_name is NULL, aa and pos are necessary to creat a modified_name")
  }

  if(is.null(modified_name)){
    data$gene_name = ifelse(data[, gene_name] == "" , data[ , protein_ID] , data[ , gene_name]) %>%
      gsub(paste0(delim, ".*"), "", .)
    data$protein_ID = ifelse(data[, protein_ID] == "" , data[ , gene_name] , data[ , protein_ID]) %>%
      gsub(paste0(delim, ".*"), "", .)
    data$modified_pos = data[,pos] %>%
      gsub(paste0(delim, ".*"), "", .)
    data$modified_aa = data[,aa] %>%
      gsub(paste0(delim, ".*"), "", .)
    # data %<>% filter(Reverse=="") %>% filter(Potential.contaminant=="")
    data$PTM_ID = paste(data[ , "protein_ID"], "_", data[ , aa] , data[ , pos] ,sep="")
    data$PTM_name = paste(data[, "gene_name"], "_" , data[ , aa] , data[ , pos],sep="")

    data2 = make_unique(data,names= "PTM_name",ids = "PTM_ID")
  }else{
    data$PTM_name = data[,modified_name] %>%
      gsub(paste0(delim, ".*"), "", .)
    data$PTM_ID = data$PTM_name
    data$modified_pos = data$PTM_name %>% gsub(".*_", "", .) %>% str_extract("[0-9]+")
    data$modified_aa = data$PTM_name %>% gsub(".*_", "", .) %>% str_extract("[a-zA-Z]+")
    data$gene_name = data$PTM_name %>% gsub("_[^_]*$", "", .)
    data$protein_ID = data$PTM_name %>% gsub("_[^_]*$", "", .)

    data2 = make_unique(data,names= "PTM_name",ids = "PTM_ID")
  }

  return(data2)
}




#' correct_PTM_by_Protein
#'
#' Adjust modified-enrich peptide quantities (PTM relative proteomics) by a relative global proteomics data via matching
#' \code{correct_key} and \code{correct_level}
#'
#' @param enriched_peptide The SummarizedExperiment object of modified-relative proteomics.
#' @param relative_protein The SummarizedExperiment object of the relative global proteomics
#' @param correct_key The key identifier column to match PTM peptides and proteins, one of "name", "ID"
#' @param correct_level Character(1), how to match experiment design, should be one of "condition" or "replicate"
#' @param unidentified_treatment Character(1), one of "retain", "remove", how to treat the PTM peptides whose proteins are
#' unidentified in the relative global proteomics
#'
#' @return
#' A modified-relative proteomics SummarizedExperiment object with adjusted quantities
#'
#' @export
#'
correct_PTM_by_Protein = function(enriched_peptide , relative_protein, correct_key = c("name","ID"),
                                  correct_level = c("condition", "replicate"), unidentified_treatment = c("retain", "remove")) {
  assertthat::assert_that(inherits(enriched_peptide, "SummarizedExperiment"),
                          inherits(relative_protein, "SummarizedExperiment"),
                          is.character(correct_key),  length(correct_key) == 1,
                          is.character(unidentified_treatment),  length(unidentified_treatment) == 1)
  if(!correct_key %in% c("name", "ID")){
    stop("correct key should be one of name/ID",call. = F)
  }
  if(!unidentified_treatment %in% c("retain", "remove")){
    stop("unidentified_treatment should be one of retain/remove",call. = F)
  }
  correct_level = match.arg(correct_level)
  unidentified_treatment = match.arg(unidentified_treatment)

  protein_assay = assay(relative_protein)
  protein_df_wide = get_df_wide(relative_protein)
  protein_design <- relative_protein@colData

  key_col = ifelse(correct_key == "name", "gene_name", "protein_ID")

  enriched_peptide2 <- enriched_peptide
  if(unidentified_treatment == "remove")
    enriched_peptide2 = enriched_peptide2[enriched_peptide2@elementMetadata[, key_col] %in% protein_df_wide[, correct_key],]

  PTM_assay = assay(enriched_peptide2)
  PTM_design <- enriched_peptide2@colData

  protein_assay2 = protein_assay - rowMeans(protein_assay) ## center proteingroup quantity
  protein_assay2 = data.frame(rowname = protein_df_wide[, correct_key] , protein_assay2)
  colnames(protein_assay2)[1] = "key"
  protein_assay2 <- gather(protein_assay2, key = label, value = "pro_expression", -"key")
  protein_assay2[,correct_level] = protein_design[match(protein_assay2$label, protein_design$label),correct_level]
  # protein_assay2$condition = protein_design$condition[match(protein_assay2$label, protein_design$label)]

  ## calculate mean centered quantity of each condition
  thegroups <- c(correct_level, "key")

  protein_assay3 = protein_assay2 %>%
    group_by_at(vars(one_of(thegroups))) %>%
    # group_by(.dots = thegroups) %>%
    summarise(pro_expression = mean(pro_expression))

  PTM_assay2 = PTM_assay %>% data.frame() %>% rowid_to_column()
  PTM_assay2[,"key"] = enriched_peptide2@elementMetadata[, key_col]
  PTM_assay2 <- gather(PTM_assay2, key = label, value = "expression", -c("rowid","key"))
  PTM_assay2[,correct_level] = PTM_design[match(PTM_assay2$label, PTM_design$label), correct_level]
  # PTM_assay2$condition = PTM_design$condition[match(PTM_assay2$label, PTM_design$label)]
  PTM_assay2 %>% head()

  ## PTM quantity minus relative proteingroup quantity in different condition
  PTM_assay3 = left_join(PTM_assay2,protein_assay3 , by= c("key",correct_level))
  PTM_assay3$pro_expression[is.na(PTM_assay3$pro_expression)] = 0
  PTM_assay3$expression = PTM_assay3$expression - PTM_assay3$pro_expression

  PTM_assay4 = spread(PTM_assay3[,c("rowid","label","expression")],key = label,value = expression  ) %>%
    arrange(rowid) %>% .[,colnames(enriched_peptide2)] %>% `rownames<-` (rownames(enriched_peptide2))


  assay(enriched_peptide2) = PTM_assay4

  return(enriched_peptide2)
}







